//
// Created by wuzhe on 2022/3/30.
//

#ifndef UNIVERSEROOM_SPACE_HH
#define UNIVERSEROOM_SPACE_HH

#include <list>
#include <map>
#include "Room.hh"
#include "UniverseDatagram.hh"
#include "RedisUtils.h"
#include "RedisAsyncUtils.h"
#include "Entity.h"

// 客户端行为type
#define ENTER        1 // 进入space
#define EXIT         2 // 离开space
#define CREATE_ROOM  3 // 创建房间
#define ENTER_ROOM   4 // 进入房间
#define DEL_ROOM     5 // 删除房间
#define EXIT_ROOM    6 // 退出房间
#define CREATE_ROLE  7 // 创建角色
#define TALK         8 // 发送消息
#define HISTORY1     9 // 获取聊天历史
#define ROOM_LIST1    10 // 获取room list

// 服务器端行为
#define NEED_ROLE    21 // 角色创建请求
#define HISTORY2     22 // 发送历史消息
#define BROADCAST    23 // 广播角色发送消息
#define ROOM_LIST2   24 // SEND room list
#define RECONNECT    25 // reconnect
#define SEND_ROOM    26 // 发送给从服务器room id
#define SEND_PLAYER  27 // 发送给从服务器玩家信息

// ALL
#define ACK          31 // 确认
#define ERR          32 // 错误

// slave
#define SLAVE_REGISTER  41
#define SLAVE_  UNREGISTER  42

class Slave;
extern bool isMain;
/**
 * 聊天室
 * Singleton
 */
class Space {
private:
    Space();
    int roomIncreaseId = 0;
    std::map<std::string, Slave*> roomName2Slave;
    // entity
    std::map<std::string, Entity*> entityMap;
    std::map<std::string, Player*> playerMap;
    std::map<std::string, Slave*> slaveMap;
    std::map<int, std::string> roomId2nameMap;
    std::list<std::string> roomNameList;
//    Redis redis;
    RedisAsync *redis;
    int num = 0;
    bool isInit = false;

    // just for slave server
    Slave *slave = nullptr;
public:
    /**
     * 从服务器拥有room实体
     */
    std::map<int, Room*> roomMap;

    static Space& getSingleton() {
        static Space space;
        return space;

    }
    /**
     * slave启动结束
     */
    void onSlaveBoot();
    int getNum();
    void setNum(int num);
    void createRoom(const std::string& roomName, Player* player);
    Entity& createEntity(int fd, const std::string& IP);

    void processDatagram(ParseRes &res, const std::string& ip);

    void send2Client(Player *player, char type, const std::string& content = "");
    void send2Master(char type, const std::string &content = "");
    void send2Slave(Slave *slave, char type, const std::string& content = "");

    void sendRoomList(Player *player, std::string filter);

    void onEnterRoom(Player *player, int roomId);

    void getroomNameList();

    void onExitRoom(Player *player, int roomId);

    void processDisconnect(const std::string& IP);

    void recordMsg(Room *room, const Msg& msg);

    void updatePlayerInfo(Player *player);

    void onExit(Player *player);

    void getPlayerInfo(Player *player, std::function<void(std::string)> cbFunc);

    void initRoomHistory(Room *room, int count);

    void processMainResp(ParseRes &res);

    void instRoom(std::string roomName, int roomId);
};



#endif //UNIVERSEROOM_SPACE_HH
